# -*- coding:utf-8 -*-
# !/usr/bin/python

import os
import sys
import shutil
import datetime
import time
import serial    
import thread
import struct
import mt_ota
import binascii
from ctypes import *

def printusage():
    print "Usage:"
    print "     sudo python *.py serialnumber baud"
    return;

def sendMessage2BLEandGetResponse(ser,msg,res=0):
    n = ser.write(msg)    
    print "Send: %d %s" % (n,msg),
    r = ser.readall()
    if len(r) == 0:
        print "No Response\n",
    else:
        print "Get : %s" % (r),
    if res == 0:
        return r;
    if r == res:
        return 1;
    else:
        return 0;

def serialRX(threadName,ser):
    while 1:
        serialrxbuf = ser.readall()
        print serialrxbuf

def serialTx(threadName,ser):
    while 1:
        print "Time: %s.%d" % (time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())),datetime.datetime.now().microsecond)
        workstyle = sendMessage2BLEandGetResponse(ser,'at+bleWorkstyle?\r\n')[13:14]
        consta = sendMessage2BLEandGetResponse(ser,'at+consta?\r\n')[7:9]
        
        if workstyle == '3' and consta != 'FF':
            sendMessage2BLEandGetResponse(ser,'%d' % sn + '=====>------>asfsjghajsdghasjghdajgdiiiieryerharehasdhadhadfjhad,jfghadfjg4536376917967261haidsjasfgasdhasdghadsjg!@#$%^&**(()_+-=gghdhdhhuyyweyyw6468sjdfj)1234567890\r\n')
            sn = sn + 1
        elif workstyle == '3' and consta == 'FF':
            sn = 0
            sendMessage2BLEandGetResponse(ser,usradvdata)
            usradvdata[14] = (usradvdata[14] + 1) & 0xff
            time.sleep(interval_time/1000.0) 
        print "\r\n"

def handle_message(header,data):
    dl = (((header.type_hilen&0x07) << 8) + header.lolen)
    if dl != len(data):
        #print header.type_hilen,header.lolen,header.cls,header.method,tuple(data)
        #print 'error,length not same'
        return False
    msg = (header.method << 24) + (header.cls << 16) + (header.lolen << 8) + header.type_hilen
    #print header.type_hilen,header.lolen,header.cls,header.method,tuple(data)
    #print hex(msg & 0xffff00f8)
    mtotaheader = mt_ota.mt_ota_header()
    mtotaheader.begin = 0xBEBE
    mtotaheader.pkgtype = 0x31
    mtotaheader.sn = 0x00
    if (msg & 0xffff00f8) == 0x00000020:#同步
        mtotaheader.dlen = 12
        otaheader = mt_ota.ota_header(0xa0,0x04,0x00,0x00,0x00)
        if data[0] == 0x02:
            print 'sync ok,upload bluetooth firmware'
            mtotaheader.datas = tuple(bytearray(otaheader) + '\x00\x00\x01\x00\xED\xED')#(otaheader.type_hilen,otaheader.lolen,otaheader.cls,otaheader.method,otaheader.address,0x00,0x00,0x01,0x00,0xED,0xED)
        elif data[0] == 0x10:
            print 'sync ok,upload mainmcu firmware'
            mtotaheader.datas = tuple(bytearray(otaheader) + '\x01\x00\x01\x00\xED\xED')#(otaheader.type_hilen,otaheader.lolen,otaheader.cls,otaheader.method,otaheader.address,0x01,0x00,0x01,0x00,0xED,0xED)
        elif data[0] == 0x11:
            print 'sync ok,upload hr senser firmware'
            mtotaheader.datas = tuple(bytearray(otaheader) + '\x03\x00\x01\x00\xED\xED')#(otaheader.type_hilen,otaheader.lolen,otaheader.cls,otaheader.method,otaheader.address,0x03,0x00,0x01,0x00,0xED,0xED)
        elif data[0] == 0x00:
            print 'sync ok,upload'
            mtotaheader.datas = tuple(bytearray(otaheader) + '\x00\x00\x00\x00\xED\xED')#(otaheader.type_hilen,otaheader.lolen,otaheader.cls,otaheader.method,otaheader.address,0x00,0x00,0x00,0x00,0xED,0xED)
        #print binascii.b2a_hex(bytearray(mtotaheader)[0:15])
        ser.write(bytearray(mtotaheader)[0:mtotaheader.dlen+7])    
    elif (msg & 0xffff00f8) == 0x02000020:#下载
        #下位机接收时应先解密，再存储
        with open('firmware.ota','a') as fo:
            fo.write(bytearray(data))
        mtotaheader.dlen = 10
        otaheader = mt_ota.ota_header(0x20,0x02,0x00,0x02,0x00)
        mtotaheader.datas = tuple(bytearray(otaheader)) + ( dl & 0xff,(dl >> 8) & 0xff,0xED,0xED)#(otaheader.type_hilen,otaheader.lolen,otaheader.cls,otaheader.method,otaheader.address,dl & 0xff,(dl >> 8) & 0xff,0xED,0xED)
        ser.write(bytearray(mtotaheader)[0:mtotaheader.dlen+7])    
        #print '\rloading...\r',
    elif (msg & 0xffff00f8) == 0x03000020:#完成
        print '\r\nload finish'
        mtotaheader.dlen = 8
        otaheader = mt_ota.ota_header(0x20,0x02,0x00,0x03,0x00)
        mtotaheader.datas = tuple(bytearray(otaheader) + '\x01\x00\xED\xED')#(otaheader.type_hilen,otaheader.lolen,otaheader.cls,otaheader.method,otaheader.address,0x01,0x00,0xED,0xED)
        ser.write(bytearray(mtotaheader)[0:mtotaheader.dlen+7])    
        print 'verify...'
        #verify
        time.sleep(1)

        mtotaheader.datas = tuple(bytearray(otaheader) + '\x02\x00\xED\xED')#(otaheader.type_hilen,otaheader.lolen,otaheader.cls,otaheader.method,otaheader.address,0x02,0x00,0xED,0xED)
        ser.write(bytearray(mtotaheader)[0:mtotaheader.dlen+7])    
        print 'verify success,upgradeing...'
        #upgrade
        time.sleep(1)

        mtotaheader.datas = tuple(bytearray(otaheader) + '\x03\x00\xED\xED')#(otaheader.type_hilen,otaheader.lolen,otaheader.cls,otaheader.method,otaheader.address,0x03,0x00,0xED,0xED)
        ser.write(bytearray(mtotaheader)[0:mtotaheader.dlen+7])    
        print 'upgrade success'
        exit()


def serial_input(ser):
    r = ser.read(1)
    if len(r) == 0:
        return None
    if (ord(r) & 0xff == 0xBE) and (ord(ser.read(1)) != 0xBE):
        return None
    r = ser.read(3)
    if len(r) == 0:
        return None
    r = ser.read(1)
    if len(r) == 0:
        return None
    if ord(r)&0xf8 != 0x20:
        return None
    r = r + ser.read(7)    
    otaheader = mt_ota.ota_header.from_buffer(bytearray(r))
    dl = (((otaheader.type_hilen&0x07) << 8) + otaheader.lolen)
    if dl > 0:
        data = ser.read(dl)
    else:
        data = ''
    print binascii.b2a_hex(bytearray(r)),binascii.b2a_hex(bytearray(data))
    handle_message(otaheader,map(ord,data))
    
    return otaheader,map(ord,data)


if __name__ == '__main__':

    if(len(sys.argv) < 3):
        printusage()
        exit()

    ser = serial.Serial(sys.argv[1],int(sys.argv[2]),timeout=0.015)    
    while (0 == sendMessage2BLEandGetResponse(ser,'AT+\r\n','03:OK\r\n')):
        pass

    print 'sync...'
    while True:
        serial_input(ser)
         
    exit()

